package com.bocloud.cmp.service.resource;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.bocloud.cmp.dao.CloudServerDao;
import com.bocloud.cmp.dao.ClusterDao;
import com.bocloud.cmp.dao.DataStoreDao;
import com.bocloud.cmp.dao.HostSystemDao;
import com.bocloud.cmp.dao.SnapshotDao;
import com.bocloud.cmp.entity.resource.CloudServer;
import com.bocloud.cmp.entity.resource.Cluster;
import com.bocloud.cmp.entity.resource.DataStore;
import com.bocloud.cmp.entity.resource.HostSystem;
import com.bocloud.cmp.entity.resource.Snapshot;
import com.bocloud.cmp.interfaces.resource.DataStoreService;
import com.bocloud.cmp.model.DataStoreBean;
import com.bocloud.common.enums.BaseStatus;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.Sign;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service("dataStoreService")
public class DataStoreServiceImpl implements DataStoreService {

	private static final Logger logger = LoggerFactory.getLogger(DataStoreServiceImpl.class);
	@Autowired
	private DataStoreDao dataStoreDao;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private CloudServerDao cloudServerDao;
	@Autowired
	private HostSystemDao hostSystemDao;
	@Autowired
	private ClusterDao clusterDao;
	@Autowired
	private SnapshotDao snapshotDao;

	@Override
	public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
		GridBean gridBean = null;
		try {
			if (null == params) {
				params = Lists.newArrayList();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			int total = 0;
			if (simple) {
				total = this.dataStoreDao.simpleCount(params);
				List<SimpleBean> beans = this.dataStoreDao.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				total = this.dataStoreDao.count(params);
				List<DataStore> list = this.dataStoreDao.list(page, rows, params, sorter);
				Long vendorId = null;
				for (Param param : params) {
					if (param.getSign() == Sign.EQ) {
						for (String key : param.getParam().keySet()) {
							if (key.equals("vendorId") && !StringUtils.isEmpty(param.getParam().get(key).toString())) {
								vendorId = Long.valueOf(param.getParam().get(key).toString());
								break;
							}
						}
					}
				}
				List<CloudServer> cloudServers = cloudServerDao.listByVid(vendorId);
				if (null != cloudServers && null != list) {
					for (DataStore dataStore : list) {
						if ((cloudServers.size()) - (dataStore.getVmNum()) > 0) {
							dataStore.setVmNumUm((cloudServers.size()) - (dataStore.getVmNum()));
						}
					}
				}
				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BsmResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query dataStore list fail:", e);
			return new BsmResult(false, "查询失败");
		}
	}

	@Override
	public BsmResult create(DataStore dataStore) {
		try {
			dataStore.setStatus(BaseStatus.NORMAL.name());
			dataStoreDao.save(dataStore);
		} catch (Exception e) {
			logger.error("Create dataStore fail:", e);
			return new BsmResult(false, "添加失败");
		}
		return new BsmResult(true, dataStore, "添加成功");
	}

	@Override
	public BsmResult modify(DataStoreBean bean, Long userId) {
		String path = DataStore.class.getSimpleName() + "_" + bean.getId();
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			DataStore dataStore = this.dataStoreDao.query(bean.getId());
			if (null == dataStore) {
				logger.warn("DataStore does not exist!");
				return new BsmResult(false, "数据不存在");
			}
			BeanUtils.copyProperties(bean, dataStore);
			dataStore.setMenderId(userId);
			this.dataStoreDao.update(dataStore);
			return new BsmResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify dataStore fail:", e);
			return new BsmResult(false, "修改失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult remove(Long id, Long userId) {
		String path = DataStore.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			DataStore object = this.dataStoreDao.query(id);
			if (null == object) {
				logger.warn("DataStore does not exist!");
				return new BsmResult(false, "数据不存在");
			}
			this.dataStoreDao.remove(id, userId);
			return new BsmResult(true, "删除成功");
		} catch (Exception e) {
			logger.error("Remove dataStore error:", e);
			return new BsmResult(false, "删除失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult detail(Long id) {
		try {
			DataStore dataStore = this.dataStoreDao.query(id);
			if (null == dataStore) {
				return new BsmResult(false, "数据不存在");
			}
			return new BsmResult(true, dataStore, "查询详情成功");
		} catch (Exception e) {
			logger.error("Get dataStore error：", e);
			return new BsmResult(false, "查询详情失败");
		}
	}

	@Override
	public BsmResult servers(Long id) {
		try {
			List<CloudServer> servers = this.cloudServerDao.listByStore(id);
			for (CloudServer server : servers) {
				// 设置主机名称
				HostSystem hostSystem = hostSystemDao.query(server.getHostId());
				if (null != hostSystem) {
					server.setHostName(hostSystem.getName());
					// 设置集群名称
					if (null != hostSystem.getClusterId()) {
						Cluster cluster = clusterDao.query(hostSystem.getClusterId());
						if (null != cluster) {
							server.setClusterName(cluster.getName());
						}
					}
				}
				// 设置快照数量
				List<Snapshot> snapshots = snapshotDao.listByVMid(server.getId());
				server.setSnapshotCount(snapshots.size());
			}
			return new BsmResult(true, servers, "查询虚拟机成功");
		} catch (Exception e) {
			logger.error("List cloudServer error：", e);
			return new BsmResult(false, "查询虚拟机失败");
		}
	}

	@Override
	public BsmResult hosts(Long id) {
		try {
			List<HostSystem> hosts = this.hostSystemDao.listByStore(id);
			if (null != hosts) {
				for (HostSystem host : hosts) {
					Cluster cluster = clusterDao.query(host.getClusterId());
					if (null != cluster) {
						host.setClusterName(cluster.getName());
					}
				}
			}
			return new BsmResult(true, hosts, "查询宿主机成功");
		} catch (Exception e) {
			logger.error("List hostSystem error：", e);
			return new BsmResult(false, "查询宿主机失败");
		}
	}

}
